package com.chenwc.tencentcos;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.JSONWriter;
import com.qcloud.cos.model.Bucket;
import com.qcloud.cos.model.BucketVersioningConfiguration;
import com.qcloud.cos.model.CannedAccessControlList;
import com.qcloud.cos.model.PartETag;
import org.apache.commons.lang3.StringUtils;
import org.junit.jupiter.api.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @author chenwc
 * @date 2024/4/8 23:33
 */
public class CosTest {

    private static final Logger log = LoggerFactory.getLogger(CosTest.class);

    /**
     * 在测试类执行之前执行的方法 必须用static
     */
    @BeforeAll
    public static void beforeAll() {
        CosUtil.setCosClient("",
                "",
                "ap-guangzhou");
    }

    @Test
    @Tag("TencentCos")
    @DisplayName("获取存储桶列表")
    void bucketList() {
        JSONArray buckets = CosUtil.bucketList();
        log.info("存储桶列表: {}", JSON.toJSONString(buckets, JSONWriter.Feature.WriteMapNullValue));
    }

    @Test
    @Tag("TencentCos")
    @DisplayName("判断存储桶是否存在")
    void isExistBucket() {
        String bucketName = "test";
        log.info("存储桶: {} 是否存在: {}", bucketName, CosUtil.isExistBucket(bucketName));
    }

    @Test
    @Tag("TencentCos")
    @DisplayName("createBucket")
    void createBucket() {
        String bucketName = "test";
        log.info("存储桶: {} 是否创建成功: {}", bucketName, CosUtil.createBucket(bucketName, CannedAccessControlList.Private));
    }

    @Test
    @Tag("TencentCos")
    @DisplayName("上传对象（单个普通上传）")
    void uploadObject() {
        String bucketName = "calvinchan-1308961508";
        String key = "wxhnyfy/";
        File file = new File("D:\\Downloads\\image.png");
        key += file.getName();
        log.info("key: {}", key);
        CosUtil.uploadObject(bucketName, key, file);
    }

    @Test
    @Tag("TencentCos")
    @DisplayName("下载对象")
    void downloadObject() {
        String bucketName = "calvinchan-1308961508";
        String key = "wxhnyfy/image.png";
        log.info("key: {}", key);
        CosUtil.downloadObject(bucketName, key, "", "D:\\Downloads\\image.png");
    }

    @Test
    @Tag("TencentCos")
    @DisplayName("删除对象")
    void deleteObject() {
        String bucketName = "calvinchan-1308961508";
        String key = "wxhnyfy/image.png";
        log.info("key: {}", key);
        CosUtil.deleteObject(bucketName, key);
    }

    @Test
    @Tag("TencentCos")
    @DisplayName("判断对象是否存在")
    void isExistObject() {
        String bucketName = "calvinchan-1308961508";
        String key = "wxhnyfy/image.png";
        log.info("key: {}", key);
        log.info("对象：{} 是否存在: {}", key, CosUtil.isExistObject(bucketName, key));
    }

    @Test
    @Tag("TencentCos")
    @DisplayName("获取对象的下载url")
    void getObjectUrl() {
        String bucketName = "calvinchan-1308961508";
        String key = "wxhnyfy/image.png";
        log.info("key: {}", key);
        log.info("对象下载URL: {}", CosUtil.getObjectUrl(bucketName, key));
    }

    @Test
    @Tag("TencentCos")
    @DisplayName("获取对象的下载url（带签名有效期）")
    void generatePresignedUrl() {
        String bucketName = "calvinchan-1308961508";
        String key = "data/image/2024/04/08/22526_vduo_2002.png";
        log.info("key: {}", key);
        log.info("对象下载URL（默认半小时）: {}", CosUtil.generatePresignedUrl(bucketName, key));
        log.info("对象下载URL（自定义有效时间）: {}", CosUtil.generatePresignedUrl(bucketName, key, 30, TimeUnit.MINUTES));
    }

    @Test
    @Tag("TencentCos")
    @DisplayName("分块上传对象（高级接口，多线程上传）")
    void uploadObjectByMutiplePart() {
        String bucketName = "calvinchan-1308961508";
        String key = "wxhnyfy/";
        File file = new File("D:\\Downloads\\mysql-wsrep-server-5.7-5.7.42-25.34.el7.x86_64.rpm");
        key += file.getName();
        log.info("key: {}", key);
        CosUtil.uploadObjectByMutiplePart(bucketName, key, file);
    }

    @Test
    @Tag("TencentCos")
    @DisplayName("查询分块上传任务")
    void listMultipartUploads() {
        String bucketName = "calvinchan-1308961508";
        String key = "wxhnyfy/mysql-wsrep-server-5.7-5.7.42-25.34.el7.x86_64.rpm";
        log.info("key: {}", key);
        String uploadId = CosUtil.listMultipartUploads(bucketName, key);
        log.info("uploadId: {}", uploadId);
        if (StringUtils.isEmpty(uploadId)) {
            log.info("key: {} 不存在对应的分块上传任务", key);
        } else {
            log.info("key: {} 存在对应的分块上传任务，uploadId为：{}", key, uploadId);
        }
    }

    @Test
    @Tag("TencentCos")
    @DisplayName("查询已上传的分块")
    void listParts() {
        String bucketName = "calvinchan-1308961508";
        String key = "wxhnyfy/ideaIU-2023.3.6.exe";
        log.info("key: {}", key);
        String uploadId = "171300574272a9f44b8f48af2bf51cfeb48b785fbc9947a3f683e44afd44c3a4a4a91bd611";
        List<JSONObject> list = CosUtil.listParts(bucketName, key, uploadId);
        log.info("List<PartETag>: {}", list);
    }

    @Test
    @Tag("TencentCos")
    @DisplayName("终止分块上传")
    void abortMultipartUpload() {
        String bucketName = "calvinchan-1308961508";
        String key = "wxhnyfy/mysql-wsrep-server-5.7-5.7.42-25.34.el7.x86_64.rpm";
        log.info("key: {}", key);
        String uploadId = "1712592004bfdec2779a4726a463ad77174e0f6e0c9187c839a09c712a9dbdc30c384f12db";
        CosUtil.abortMultipartUpload(bucketName, key, uploadId);
    }


    @Test
    @Tag("TencentCos")
    @DisplayName("分块上传对象（普通分块接口）")
    void uploadObjectMultipartUpload() {
        String bucketName = "calvinchan-1308961508";
        String key = "wxhnyfy/";
        File file = new File("D:\\Downloads\\ideaIU-2023.3.6.exe");
        key += file.getName();
        log.info("key: {}", key);
        //CosUtil.uploadObjectMultipartUpload(bucketName, key, file);
        CosUtil.uploadObjectMultipartUploadWithCosClient(bucketName, key, file);
    }

    @Test
    @Tag("TencentCos")
    @DisplayName("上传本地目录")
    void uploadDirectory() {
        String bucketName = "calvinchan-1308961508";
        String key = "wxhnyfy/";
        File file = new File("D:\\Downloads\\123456");
        key += file.getName();
        log.info("key: {}", key);
        CosUtil.uploadDirectory(bucketName, key, file, true);
    }

    @Test
    @Tag("TencentCos")
    @DisplayName("复制对象")
    void copy() {
        String srcBucketName = "calvinchan-1308961508";
        String srcBucketRegion = "ap-guangzhou";
        String srcKey = "wxhnyfy/image.png";
        log.info("srcKey: {}", srcKey);
        String destBucketName = "calvinchan-1308961508";
        String destKey = "wxhnyfy/123456/image.png";
        log.info("destKey: {}", destKey);
        CosUtil.copy(srcBucketRegion, srcBucketName, srcKey, destBucketName, destKey);
    }

    @Test
    @Tag("TencentCos")
    @DisplayName("deleteObjectByVersionId")
    void deleteObjectByVersionId() {
        String bucketName = "calvinchan-1308961508";
        String key = "wxhnyfy/image.png";
        String versionId = "MTg0NDUwMzEwNTY5MDYxNDA5MjI";
        CosUtil.deleteObject(bucketName, key, versionId);
    }

    @Test
    @Tag("TencentCos")
    @DisplayName("getObjectMetadata")
    void getObjectMetadata() {
        String bucketName = "calvinchan-1308961508";
        String key = "wxhnyfy/image.png";
        JSONArray jsonArray = CosUtil.getObjectMetadata(bucketName, key, true);
        log.info("ObjectMetadata: {}", jsonArray);
    }

    @Test
    @Tag("TencentCos")
    @DisplayName("getBucketVersion")
    void getBucketVersion() {
        String bucketName = "calvinchan-1308961508";
        String bucketVersion = CosUtil.getBucketVersion(bucketName);
        log.info("bucketVersion: {}", bucketVersion);
    }

    @Test
    @Tag("TencentCos")
    @DisplayName("setBucketVersion")
    void setBucketVersion() {
        String bucketName = "calvinchan-1308961508";
        BucketVersioningConfiguration bucketVersioningConfiguration = new BucketVersioningConfiguration();
        bucketVersioningConfiguration.setStatus(BucketVersioningConfiguration.SUSPENDED);
        CosUtil.setBucketVersion(bucketName, bucketVersioningConfiguration);
    }

    /**
     * 在每个测试用例后执行的方法 必须用static声明
     */
    @AfterAll
    public static void afterAll() {
        CosUtil.closeCosClient();
    }

}
